﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ReactiveUI.Fody.Helpers;
using S7.Net.Types;
using System.Collections.ObjectModel;
using System.Windows;
using Common.Utils;

namespace Common.ViewModels
{
    /// <summary>
    /// 摆渡站点
    /// </summary>
    [Serializable]
    [JsonObject(MemberSerialization.OptOut)]
    public class BoatStation : ViewModelBase
    {
        public double Position { get; set; }
    }


    /*这里需要解决对象站点来车的问题  站点面临  A->站点1  B->站点1*/

    /// <summary>
    /// 站点(这里使用Point3D,不再使用)
    /// </summary>
    [Serializable]
    [JsonObject(MemberSerialization.OptOut)]
    public class Station : ViewModelBase
    {

        public Station()
        {
            MessageAggregator<LoadedMsg>.Subscribe(OnLoadedMsg);
        }

        [Reactive]public string Name { get; set; }

        //public void Add(工件 工件)
        //{
        //    this
        //}


        /// <summary>
        /// 完成之后
        /// </summary>
        /// <param name="obj"></param>
        private void OnLoadedMsg(LoadedMsg obj)
        {
            //m_IDisposable.Add()
            //根据wei
            var point3D = this.PassVMPosition.PassVM.GetPoint3D(this.PassVMPosition,true);
            this.Point3D.Update(point3D);//更新小车位置
        }

        

        /// <summary>
        /// 圆心尺寸
        /// </summary>
        [JsonProperty]
        [Reactive] public double CenterSize { get; set; } = 130;

        /// <summary>
        /// 边框厚度
        /// </summary>
        [JsonProperty]
        [Reactive] public double StrokeThickness { get; set; } = 50;

        /// <summary>
        /// 字体大小
        /// </summary>
        [Reactive]
        [JsonProperty]
        public double FontSize { get; set; } =154;

        /// <summary>
        /// 字体Margin
        /// </summary>
        [JsonProperty]
        [Reactive] public Thickness TypeFaceMaggin { get; set; } = new(0);

        /// <summary>
        /// 站点介绍
        /// </summary>
        [Reactive]
        [JsonProperty]
        public string Description { get; set; } = "站点介绍";

        /// <summary>
        /// 鼠标悬浮字体大小
        /// </summary>
        [Reactive] public double ToolTipFontSize { get; set; } = 50;

        /// <summary>
        /// 点的位置(世界坐标系的位置,唯一位置)
        /// </summary>
        [Reactive] public Point3D Point3D { get; set; } = new();

        [Reactive] public Point3D RealPoint3D { get; set; } = new();

        /// <summary>
        /// 是否摆渡站点
        /// </summary>
        [Reactive] public bool IsBoatStation { get; set; }

        /// <summary>
        /// 属于摆渡组的站点
        /// </summary>
        [Reactive] public bool IsBoatGroupStation { get; set; }

        /// <summary>
        /// 主通道站点(主通道最多只能两个小车)
        /// </summary>
        [Reactive] public bool 是否主通道站点 { get; set; }


        /// <summary>
        /// 如果是周转站点  需要取号,并且需要避让
        /// </summary>
        [Reactive]
        public bool 是否周转站点 { get; set; }

        //[Reactive]public 取号叫号系统 取号叫号系统 {  get; set; }

        /// <summary>
        /// 这里根据不同的站点计算位置 在A通道为位置1 在b通道为位置2
        /// </summary>
        public ObservableCollection<PassVMPosition> PassVMPositions { get; set; } = new();

        /// <summary>
        /// 显示用的PassVMPosition(用来更新位置),
        /// </summary>
        [Reactive] public PassVMPosition PassVMPosition { get; set; }

        //[Reactive] public PassVMPosition PassVMPosition1 { get; set; } = new();

        //[Reactive] public PassVMPosition PassVMPosition2 { get; set; } = new();

        public void UpdatePosition()
        {
            
        }

        /// <summary>
        /// 这里取消了摆渡站点
        /// </summary>
        [Reactive] public BoatStation BoatStation { get; set; }

        /// <summary>
        /// 临接站点集合(由after计算得出)
        /// </summary>
        [Reactive] public List<Station> 临接站点 { get; set; } = new();

        private static readonly object m_lockGetMove=new object();

        /// <summary>
        /// 是否锁定
        /// </summary>
        [JsonIgnore]
        [Reactive]
        public bool IsLock { get; set; }

        /// <summary>
        /// 获取站点能否移动。锁定的站点不可移动
        /// </summary>
        /// <returns></returns>
        public bool GetCanMoveAnd()
        {
            if (this.IsLock)
            {
                return false;
            }

            lock (m_lockGetMove)
            {
                if (this.IsLock)
                {
                    return false;
                }

                this.IsLock=true;
                return true;
            }
        }

        /// <summary>
        /// 离开站点之后解除锁定 解除锁定,假设走到一半抛锚了,重新启动将会导致撞车,这里暂停之后重新进入 ()
        /// </summary>
        public void ReleaseLock()
        {
            lock (m_lockGetMove)
            {
                this.IsLock=false;
            }
        }

        public void Lock()
        {
            lock (m_lockGetMove)
            {
                this.IsLock = true;
            }
        }

        //[Reactive]public Station 
    }

    public class PassVMPosition : BaseViewModel, IPosition
    {
        /// <summary>
        /// 站点当前通道(一个站点可能有多个通道,既处于竖直方向的通道，又属于垂直方向的通道)
        /// </summary>
        [Reactive] public PassVM PassVM { get; set; }

        /// <summary>
        /// 位置
        /// </summary>
        [Reactive] public double Position { get; set; }
    }

    /// <summary>
    /// 区别与站点 系统由节点和边组成 这里难点在于 
    /// </summary>
    [Serializable]
    [JsonObject(MemberSerialization.OptOut)]
    public class 节点 : ViewModelBase
    {
        /// <summary>
        /// 节点名
        /// </summary>
        [Reactive] public string Name { get; set; }

        /// <summary>
        /// 节点位置
        /// </summary>
        [Reactive]
        public Point3D Point3D { get; set; } = new Point3D();

        /// <summary>
        /// 被占用的节点将不可用
        /// </summary>
        [Reactive] public bool 是否可用 { get; set; }

        [Reactive] public int ArrayIndex { get; set; }


    }

    /// <summary>
    /// 节点的边组成(长边-短边 边没有方向)
    /// </summary>
    [Serializable]
    [JsonObject(MemberSerialization.OptOut)]
    public class 边 : ViewModelBase
    {
        /// <summary>
        /// 消耗时间
        /// </summary>
        [Reactive] public double Time { get; set; }

        [Reactive] public bool 存在边 { get; set; }


    }

    /// <summary>
    /// 图由节点和边组成(移动直接查图)
    /// </summary>
    [Serializable]
    [JsonObject(MemberSerialization.OptOut)]
    public class 图 : ViewModelBase
    {

    }

    /// <summary>
    /// 图由节点和边组成(移动直接查图 这里采用局部地区使用临接矩阵,局部地区使用链表)
    /// </summary>
    [Serializable]
    [JsonObject(MemberSerialization.OptOut)]
    public class 节点矩阵 : ViewModelBase
    {

    }





}
